<template>
    <el-card class="box-card">
        <template #header>
            <el-row>
                <el-col :span="24">
                    <el-button type="primary" :icon="Plus" @click="handleAdd(null)">添加主菜单</el-button>
                </el-col>
            </el-row>
        </template>
        <el-table :data="state.tableData" row-key="id" default-expand-all>
            <el-table-column prop="title" label="标题" min-width="150" />
            <el-table-column label="图标" width="52" align="center">
                <template #default="scope">
                    <Icon :name="scope.row.icon" />
                </template>
            </el-table-column>
            <el-table-column prop="name" label="名称" min-width="100" />
            <el-table-column prop="alias" label="别名" />
            <el-table-column prop="path" label="路径" min-width="150" show-overflow-tooltip />
            <el-table-column prop="component" label="页面" min-width="150" show-overflow-tooltip />
            <el-table-column prop="redirect" label="重定向" show-overflow-tooltip />
            <el-table-column label="缓存" align="center" width="52">
                <template #default="scope">
                    <el-tag size="small" :type="scope.row.cache ? 'success' : 'info'">
                        {{ scope.row.cache ? '是' : '否' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="布尔模式" align="center" min-width="80">
                <template #default="scope">
                    <el-tag size="small" :type="scope.row.props ? 'success' : 'info'">
                        {{ scope.row.props ? '是' : '否' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="标签固定" align="center" width="80">
                <template #default="scope">
                    <el-tag size="small" :type="scope.row.close ? 'info' : 'success'">
                        {{ scope.row.close ? '否' : '是' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="侧边导航" align="center" min-width="80">
                <template #default="scope">
                    <el-tag size="small" :type="scope.row.aside ? 'success' : 'info'">
                        {{ scope.row.aside ? '显示' : '隐藏' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="标签导航" align="center" min-width="80">
                <template #default="scope">
                    <el-tag size="small" :type="scope.row.label ? 'success' : 'info'">
                        {{ scope.row.label ? '显示' : '隐藏' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column label="文本导航" align="center" min-width="80">
                <template #default="scope">
                    <el-tag size="small" :type="scope.row.breadcrumb ? 'success' : 'info'">
                        {{ scope.row.breadcrumb ? '显示' : '隐藏' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column fixed="right" label="排序" align="center" width="52">
                <template #default="scope">
                    <el-tag size="small">{{ scope.row.sort }}</el-tag>
                </template>
            </el-table-column>
            <el-table-column fixed="right" label="状态" align="center" width="54">
                <template #default="scope">
                    <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1"
                        @change="changeStatus(scope.row)" size="small" />
                </template>
            </el-table-column>
            <el-table-column fixed="right" label="操作" :width="device ? 72 : 174" align="center">
                <template #default="scope" v-if="device">
                    <el-dropdown>
                        <span class="el-dropdown-link">
                            操作
                            <el-icon class="el-icon--right">
                                <arrow-down />
                            </el-icon>
                        </span>
                        <template #dropdown>
                            <el-dropdown-menu>
                                <el-dropdown-item @click="handleAdd(scope.row)">添加子菜单</el-dropdown-item>
                                <el-dropdown-item divided @click="handleEdit(scope.row)">编辑</el-dropdown-item>
                                <el-dropdown-item @confirm="handleDelete(scope.row.id)">删除</el-dropdown-item>
                            </el-dropdown-menu>
                        </template>
                    </el-dropdown>
                </template>

                <template #default="scope" v-else>
                    <el-button link type="primary" @click="handleAdd(scope.row)" size="small">添加子菜单</el-button>
                    <el-button link type="primary" @click="handleEdit(scope.row)" size="small">编辑</el-button>

                    <el-popconfirm title="确定要删除吗？" @confirm="handleDelete(scope.row.id)">
                        <template #reference>
                            <el-button link type="primary" size="small">删除</el-button>
                        </template>
                    </el-popconfirm>
                </template>


            </el-table-column>
        </el-table>

        <el-dialog v-model="state.dialogVisible" destroy-on-close>
            <template #header>
                {{ state.isEdit ? '编辑菜单' : '新建菜单' }}
            </template>
            <el-form ref="ruleForm" :model="state.form" label-width="80px" label-position="right" :rules="rules">
                <el-row :gutter="20" class="gutter">
                    <el-col :span="12">
                        <el-form-item label="菜单所属" prop="pid">
                            <el-tree-select v-model="state.form.pid" node-key="id" :data="state.treeData"
                                :props="{ children: 'children', label: 'title' }" :expand-on-click-node="false"
                                default-expand-all check-strictly style="width: 100%;" @change="changeTree" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="菜单图标" prop="icon">
                            <el-input v-model="state.form.icon" placeholder="选择图标" @click="state.iconDialogVisible = true">
                                <template #prepend>
                                    <Icon :name="state.form.icon" />
                                </template>
                            </el-input>
                            <template #append>
                                <el-button>选择</el-button>
                            </template>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20" class="gutter">
                    <el-col :span="12">
                        <el-form-item label="菜单标题" prop="title">
                            <el-input v-model="state.form.title" placeholder="输入菜单标题" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="页面路径" prop="path">
                            <el-input v-model="state.form.path" placeholder="输入页面路径" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20" class="gutter">
                    <el-col :span="12">
                        <el-form-item label="菜单名称" prop="name">
                            <el-input v-model="state.form.name" placeholder="输入菜单名称"
                                :formatter="(value) => `${value}`.slice(0, 1).toUpperCase() + `${value}`.slice(1).toLowerCase()" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="页面文件">

                            <el-select v-model="state.form.component" placeholder="选择页面文件" style="width: 100%;" clearable>
                                <el-option v-for="item in files" :key="item.name" :label="item.name" :value="item.name" />
                            </el-select>

                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="20" class="gutter">
                    <el-col :span="12">
                        <el-form-item label="菜单别名">
                            <el-input v-model="state.form.alias" placeholder="输入菜单别名" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="重定向">
                            <el-input v-model="state.form.redirect" placeholder="输入重定向地址" />
                        </el-form-item>
                    </el-col>
                </el-row>

                <el-row :gutter="20" class="gutter">

                    <el-col :span="24">
                        <el-form-item label="菜单排序">
                            <el-input-number v-model="state.form.sort" :min="0" />
                        </el-form-item>
                    </el-col>

                </el-row>

                <el-row :gutter="20" class="gutter">

                    <el-col :span="24">
                        <el-form-item label="显示菜单">
                            <el-checkbox v-model="state.form.aside" label="左侧菜单" />
                            <el-checkbox v-model="state.form.breadcrumb" label="文本导航" />
                            <el-checkbox v-model="state.form.label" label="标签导航" />
                        </el-form-item>
                    </el-col>
                </el-row>

                <el-row :gutter="20" class="gutter">

                    <el-col :span="8">
                        <el-form-item label="页面缓存">
                            <el-switch v-model="state.form.cache" inline-prompt :active-value="1" :inactive-value="0"
                                active-text="开启" inactive-text="关闭" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="8">
                        <el-form-item label="标签固定">
                            <el-switch v-model="state.form.close" inline-prompt :active-value="0" :inactive-value="1"
                                active-text="开启" inactive-text="关闭" />
                        </el-form-item>
                    </el-col>

                    <el-col :span="8">
                        <el-form-item label="布尔模式">
                            <el-switch v-model="state.form.props" inline-prompt :active-value="1" :inactive-value="0"
                                active-text="开启" inactive-text="关闭" />
                        </el-form-item>
                    </el-col>
                </el-row>

            </el-form>

            <template #footer>
                <div class="dialog-footer">
                    <el-button @click="state.dialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="submitForm">确认</el-button>
                </div>
            </template>
        </el-dialog>


        <el-dialog v-model="state.iconDialogVisible">
            <template #header>
                选择图标
            </template>
            <el-scrollbar height="400px">
                <div class="icon-list">
                    <ul>
                        <li v-for="(item, index) in ElementPlusIconsVue" :key="index" @click="handleIcon(item.name)">
                            <Icon :name="item.name" />
                            <p>{{ item.name }}</p>
                        </li>
                    </ul>
                </div>
            </el-scrollbar>
        </el-dialog>

    </el-card>
</template>
<script setup>
import { ref, reactive, computed } from 'vue'
import { useStore } from 'vuex'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import { Plus, Delete } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import Icon from '@/layout/icon.vue'
import Request from '@/request'

const store = useStore()
const device = computed(() => store.state.system.device)
const ruleForm = ref()

const defaultForm = {
    pid: 0,
    icon: '',
    title: '',
    path: '',
    name: '',
    component: 'Layout',
    alias: '',
    redirect: '',
    sort: 0,
    cache: false,
    aside: true,
    label: true,
    breadcrumb: true,
    close: false,
    props: false
}

const state = reactive({
    treeData: [],
    tableData: [],
    iconDialogVisible: false,
    dialogVisible: false,
    isEdit: false,
    empty: '暂无数据',
    form: JSON.parse(JSON.stringify(defaultForm))
})

const rules = {
    name: [
        { required: true, message: '请输入菜单名称！', trigger: ['blur', 'change'] },
        { min: 3, message: '长度不能低于2位！', trigger: ['blur', 'change'] }
    ]
}

const files = import.meta.glob('@/views/**/*.vue', { as: 'raw' })


const handleAdd = (row) => {
    state.form = JSON.parse(JSON.stringify(defaultForm))
    state.isEdit = false
    state.dialogVisible = true

    if (row != null) {
        state.form.pid = row.id
    }

    if (state.form.pid == 0) {
        state.form.component = 'Layout'
    } else {
        state.form.component = ''
    }
}

const handleEdit = (row) => {
    state.isEdit = true
    state.dialogVisible = true

    let field = JSON.parse(JSON.stringify(row))
    field.aside = field.aside ? true : false
    field.label = field.label ? true : false
    field.breadcrumb = field.breadcrumb ? true : false
    state.form = field
}

const handleDelete = (id) => {
    Request
        .post('system/menu/delete', { id: id })
        .then((res) => {
            if (!res.code) {
                getDataList()
            }

            ElMessage({
                message: res.message,
                type: res.code ? 'error' : 'success'
            })
        })
        .catch((error) => {
            console.log('error', error)
        })
}

const changeStatus = (row) => {
    Request
        .post('system/menu/field', { id: row.id, field: 'status', value: row.status ? 1 : 0 })
        .then((res) => {
            getDataList()
            ElMessage({
                message: res.message,
                grouping: true,
                type: res.code ? 'error' : 'success'
            })
        })
        .catch((error) => {
            console.log('error', error)
        })
}

const handleIcon = (name) => {
    state.form.icon = name
    state.iconDialogVisible = false
}

const changeTree = (value) => {
    if (value == 0) {
        state.form.component = 'Layout'
    }
}

const submitForm = () => {
    if (!ruleForm) return
    ruleForm.value.validate(valid => {
        if (valid) {
            const url = state.isEdit ? 'system/menu/edit' : 'system/menu/add'
            Request
                .post(url, state.form)
                .then((res) => {
                    if (!res.code) {
                        getDataList()
                        state.dialogVisible = false
                    }

                    ElMessage({
                        message: res.message,
                        type: res.code ? 'error' : 'success'
                    })
                })
                .catch((error) => {
                    console.log('error', error)
                })
        }
    })
}


const getDataList = () => {
    Request
        .get('system/menu/index')
        .then((res) => {
            if (res.code) {
                state.empty = res.message
            } else {
                state.tableData = res.datas
                state.treeData = [...[
                    {
                        id: 0,
                        title: '主菜单'
                    },
                ],
                ...res.datas
                ]
            }
        })
        .catch((error) => {
            console.log('error', error)
        })
}

getDataList()

</script>
<style scoped>
.icon-list {
    overflow: auto;
}

.icon-list ul {
    display: flex;
    list-style: none;
    border-top: 1px solid var(--el-border-color);
    border-left: 1px solid var(--el-border-color);
    border-radius: 4px;
    flex-wrap: wrap;
}

.icon-list .el-icon {
    font-size: 22px;
}

.icon-list ul li {
    width: 12.5%;
    display: flex;
    justify-content: center;
    align-items: center;
    border-right: 1px solid var(--el-border-color);
    border-bottom: 1px solid var(--el-border-color);
    box-sizing: border-box;
    flex-direction: column;
    padding: 10px 0;
    cursor: pointer;
    overflow: hidden;
}

.icon-list ul li:hover {
    background-color: var(--el-border-color-extra-light);
    color: var(--brand-color-light);
}

.icon-list ul li p {
    font-size: 12px;
    margin-top: 10px;
}

.scope-icon {
    display: flex;
    align-items: center;
}

.scope-icon span {
    margin-left: 5px;
}

.el-dropdown-link {
    display: flex;
    align-items: center;
}

.gutter:not(:last-of-type) {
    margin-bottom: 18px;
}
</style>